
package com.wulian.user.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.wulian.common.constants.CommonConstants;
import com.wulian.common.controller.BaseController;
import com.wulian.common.dto.UserInfo;
import com.wulian.common.util.JSONUtil;
import com.wulian.common.util.Result;
import com.wulian.common.vo.MenuVO;
import com.wulian.common.vo.UserVO;
import com.wulian.user.entity.SysMenu;
import com.wulian.user.mapper.SysMenuMapper;
import com.wulian.user.mapper.SysUserMapper;
import com.wulian.user.model.dto.MenuTree;
import com.wulian.user.service.SysMenuService;
import com.wulian.user.util.TreeUtil;

/**
 * @author Administrator
 * @date 2017/10/31
 */
@RestController
@RequestMapping("/menu")
public class MenuController extends BaseController<UserInfo> {
    @Autowired
    private SysMenuService sysMenuService;
    
    @Autowired
    private SysMenuMapper sysMenuMapper;
    
    @Autowired
    private SysUserMapper sysUserMapper;
    /**
     * 通过角色名称查询用户菜单
     *
     * @param role 角色名称
     * @return 菜单列表
     */
    @GetMapping("/findMenuByRole/{role}")
    public List<MenuVO> findMenuByRole(@PathVariable String role) {
        return sysMenuService.findMenuByRoleName(role);
    }

    /**
     * 返回当前用户的树形菜单集合
     *
     * @return 当前用户的树形菜单
     */
    @GetMapping(value = "/userMenu")
    public List<MenuTree> userMenu(String type) {
    	UserInfo user = getCurrentUser();
    	Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("username", user.getSysUser().getUsername());
		paramMap.put("status", CommonConstants.STATUS_NORMAL);
		UserVO selectUser = sysUserMapper.selectUserVoByUsername(paramMap);
    	List<String> roleCodeList = selectUser.getRoleList().stream().map(sr -> sr.getRoleCode()).collect(Collectors.toList());
        // 获取符合条件得菜单
        List<MenuVO> all = new ArrayList<>();
        roleCodeList.forEach(roleName -> all.addAll(sysMenuService.findMenuByRoleName(roleName)));
        List<MenuVO> allMenuVO = all.stream().distinct().collect(Collectors.toList());
        List<MenuVO> list = new ArrayList<>();
        for(MenuVO mv : allMenuVO){
        	SysMenu sysMenu = sysMenuMapper.selectById(mv.getParentId());
        	if(null != sysMenu && CommonConstants.DEL_FLAG_NO.equals(sysMenu.getDelFlag()) && (CommonConstants.MENU.equals(sysMenu.getType()) || CommonConstants.BUTTON.equals(sysMenu.getType()))){
        		MenuVO menuVO = new MenuVO();
        		BeanUtils.copyProperties(sysMenu, menuVO);
        		list.add(menuVO);
        	}
        	
        }
        
        allMenuVO.addAll(list);
        
        allMenuVO = allMenuVO.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(MenuVO::getMenuId))), ArrayList::new));        
        
        List<MenuTree> menuTreeList = new ArrayList<>();
        allMenuVO.forEach(menuVo -> {
        	if(StringUtils.isBlank(type)){
        		menuTreeList.add(new MenuTree(menuVo));
        	}else{
        		if (type.equals(menuVo.getType())) {
                    menuTreeList.add(new MenuTree(menuVo));
                }
        	}
            
        });
        menuTreeList.sort(Comparator.comparing(MenuTree::getSort));
        return TreeUtil.build(menuTreeList, -1);
    }

    /**
     * 返回当前用户的树形菜单集合
     *
     * @return 当前用户的树形菜单
     */
    @GetMapping(value = "/userMenuByApp")
    public List<MenuTree> userMenuByApp(@RequestParam(value = "userToken") String userToken) {
        UserInfo user = getCurrentUserByApp(userToken);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("username", user.getSysUser().getUsername());
        paramMap.put("status", CommonConstants.STATUS_NORMAL);
        UserVO selectUser = sysUserMapper.selectUserVoByUsername(paramMap);
        List<String> roleCodeList = selectUser.getRoleList().stream().map(sr -> sr.getRoleCode()).collect(Collectors.toList());
        // 获取符合条件得菜单
        List<MenuVO> all = new ArrayList<>();
        roleCodeList.forEach(roleName -> all.addAll(sysMenuService.findMenuByRoleName(roleName)));
        List<MenuTree> menuTreeList = new ArrayList<>();
        all.forEach(menuVo -> {
            if (CommonConstants.BUTTON.equals(menuVo.getType())) {
                menuTreeList.add(new MenuTree(menuVo));
            }
        });
        menuTreeList.sort(Comparator.comparing(MenuTree::getSort));
        return TreeUtil.build(menuTreeList, -1);
    }

    /**
     * 返回树形菜单集合
     *
     * @return 树形菜单
     */
    @GetMapping(value = "/allTree")
    public List<com.wulian.user.dto.MenuTree> getTree() {
    	String menuIds = getMenuIds();
        SysMenu condition = new SysMenu();
        condition.setDelFlag("0");
        List<SysMenu> sysMenus = sysMenuService.selectList(new EntityWrapper<>(condition));
        
        //非超级管理员则需要过滤菜单权限不能大于当前登录人
        if(StringUtils.isNotBlank(menuIds)){
        	 List<String> asList = Arrays.asList(menuIds.split(","));
        	sysMenus = sysMenus.stream().filter(sm -> asList.contains(String.valueOf(sm.getMenuId()))).collect(Collectors.toList());
        }
        sysMenus.sort(Comparator.comparing(SysMenu::getSort));
        List<com.wulian.user.dto.MenuTree> menuTrees = TreeUtil.bulidTree(sysMenus, -1);
        return menuTrees;
    }
    
    /**
     * 返回角色的菜单集合
     *
     * @param roleName 角色名称
     * @return 属性集合
     */
    @GetMapping("/roleTree/{roleName}")
    public List<Integer> roleTree(@PathVariable String roleName) {
        List<MenuVO> menus = sysMenuService.findMenuByRoleName(roleName);
        List<Integer> menuList = new ArrayList<>();
        for (MenuVO menuVo : menus) {
            menuList.add(menuVo.getMenuId());
        }
        return menuList;
    }

    /**
     * 通过ID查询菜单的详细信息
     *
     * @param id 菜单ID
     * @return 菜单详细信息roleList
     */
    @GetMapping("/{id}")
    public SysMenu menu(@PathVariable Integer id) {
        return sysMenuService.selectById(id);
    }

    /**
     * 新增菜单
     *
     * @param sysMenu 菜单信息
     * @return success/false
     */
    @PostMapping
    public Result<Boolean> menu(@RequestBody SysMenu sysMenu) {
    	sysMenu.setDelFlag(CommonConstants.DEL_FLAG_NO);
        return new Result<>(sysMenuService.insert(sysMenu));
    }

    /**
     * 删除菜单
     *
     * @param id 菜单ID
     * @return success/false
     * TODO  级联删除下级节点
     */
    @DeleteMapping("/{id}")
    public Result<Boolean> menuDel(@PathVariable Integer id) {
        return new Result<>(sysMenuService.deleteMenu(id));
    }

    @PutMapping
    public Result<Boolean> menuUpdate(@RequestBody SysMenu sysMenu) {
        return new Result<>(sysMenuService.updateMenuById(sysMenu));
    }
    
    //当前用户的菜单id结果集
    private String getMenuIds(){
    	UserInfo user = getCurrentUser();
   	 Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("username", user.getSysUser().getUsername());
        paramMap.put("status", CommonConstants.STATUS_NORMAL);
        UserVO selectUser = sysUserMapper.selectUserVoByUsername(paramMap);
        List<String> roleCodeList = selectUser.getRoleList().stream().map(sr -> sr.getRoleCode()).collect(Collectors.toList());
        //当前登录人是超管,则默认可以选择所有菜单权限
        if(roleCodeList.contains("ROLE_ADMIN")){
        	return null;
        }
        // 获取符合条件得菜单
        List<MenuVO> all = new ArrayList<>();
        roleCodeList.forEach(roleName -> all.addAll(sysMenuService.findMenuByRoleName(roleName)));
        
        List<MenuVO> list = new ArrayList<>();
        for(MenuVO mv : all){
        	SysMenu sysMenu = sysMenuMapper.selectById(mv.getParentId());
        	if(null != sysMenu && CommonConstants.DEL_FLAG_NO.equals(sysMenu.getDelFlag()) && (CommonConstants.MENU.equals(sysMenu.getType()) || CommonConstants.BUTTON.equals(sysMenu.getType()))){
        		MenuVO menuVO = new MenuVO();
        		BeanUtils.copyProperties(sysMenu, menuVO);
        		list.add(menuVO);
        	}
        	
        }
        
        all.addAll(list);
        
      //菜单过滤并转为Set<String>
        Set<String> menuIdList = all.stream().filter(menu -> CommonConstants.MENU.equals(menu.getType()) || CommonConstants.BUTTON.equals(menu.getType()))
        		.map(mtl -> String.valueOf(mtl.getMenuId())).collect(Collectors.toSet());
      //为避免deptIdList数据太大转换为字符串,以“,”号隔开,方便下面数据读取
    	String menuIds = menuIdList.stream().collect(Collectors.joining(","));
    	
    	return menuIds;
    }
    
    @GetMapping("/roleTreeChecked")
    public List<Integer> roleTreeChecked() {
    	UserInfo user = getCurrentUser();
    	 Map<String, Object> paramMap = new HashMap<String, Object>();
         paramMap.put("username", user.getSysUser().getUsername());
         paramMap.put("status", CommonConstants.STATUS_NORMAL);
         UserVO selectUser = sysUserMapper.selectUserVoByUsername(paramMap);
         List<String> roleCodeList = selectUser.getRoleList().stream().map(sr -> sr.getRoleCode()).collect(Collectors.toList());
         List<Integer> menuList = new ArrayList<>();
         if(null != roleCodeList && roleCodeList.size() > 0){
        	 List<MenuVO> menus = sysMenuService.findMenuByRoleName(roleCodeList.get(0));
             for (MenuVO menuVo : menus) {
                 menuList.add(menuVo.getMenuId());
             }
         }
       
        return menuList;
    } 
    
    
    @PostMapping("/getMenuParent")
    public List<Integer> getMenuParent(){
    	HashMap<String,Object> hashMap = new HashMap<String,Object>();
    	hashMap.put("del_flag", CommonConstants.DEL_FLAG_NO);
    	hashMap.put("parent_id", -1);
    	List<SysMenu> sysMenuList = sysMenuMapper.selectByMap(hashMap);
    	List<Integer> menuIdList = sysMenuList.stream().map(su -> su.getMenuId()).collect(Collectors.toList());
    	return menuIdList;
    }


}
